/*
 * @Author: dvlproad
 * @Date: 2022-06-01 15:54:52
 * @LastEditors: dvlproad
 * @LastEditTime: 2022-09-01 19:10:26
 * @Description: 数据发布管理中心
 */
import 'dart:convert';
import 'dart:io';

import 'package:app_images_action_image_pickers/app_images_action_image_pickers.dart';
import 'package:app_network/app_network.dart';
import 'package:flutter/material.dart';
import 'package:flutter_effect/flutter_effect.dart';
import 'package:flutter_network/flutter_network.dart';
import 'package:flutter_network_kit/flutter_network_kit.dart';
import 'package:path_provider/path_provider.dart';
import 'package:tsdemo/common/constants.dart';
import 'package:tsdemo/common/event_bus.dart';
import 'package:tsdemo/common/storge_shared.dart';

import './widget/tsdemo_verify_widget.dart';
import './tsdemo_publish_notifier.dart';
import './tsdemo_publish_requset_util.dart';
import './tsdemo_publish_cache_util.dart';

class PublishEvent {
  bool isUpdateAction;
  UploadState uploadState;
  double totalProgressValue;
  String successWishId;

  PublishEvent({
    this.isUpdateAction = false,
    this.uploadState,
    this.totalProgressValue,
    this.successWishId,
  });
}

class WishPublishManager {
  // 单例
  factory WishPublishManager() => _getInstance();

  static WishPublishManager get instance => _getInstance();
  static WishPublishManager _instance;

  static WishPublishManager _getInstance() {
    _instance ??= WishPublishManager._internal();
    return _instance;
  }

  WishPublishManager._internal() {
    //debugPrint('这个单例里的初始化方法只会执行一次');
    _init();
  }

  PublishModel publishModel;

  _init() {}

  ImageProvider get publishCoverImageProvider {
    ImageProvider coverImageProvider;
    if (publishModel.imageChooseModels.isNotEmpty) {
      AppImageChooseBean firstMediaBean = publishModel.imageChooseModels.first;
      coverImageProvider = firstMediaBean.imageProvider;
      if (publishModel.imageChooseModels.first.mediaType ==
          UploadMediaType.video) {
        coverImageProvider =
            publishModel.coverImageChooseModel?.imageProvider ??
                coverImageProvider;
      }
    }
    coverImageProvider ??= const AssetImage('images/common/placeholder.png');
    return coverImageProvider;
  }

  UploadState get currentUploadState => _currentUploadState;
  UploadState _currentUploadState = UploadState.noPublish;

  Future<bool> requestPublish(
    BuildContext context,
    bool isUpdateBusiness,
    PickPhotoAllowType pickAllowType, {
    void Function(UploadState uploadState, double totalProgressValue)
        uploadStateProgressBlock,
    void Function(ResponseModel responseModel) publishCompleteHandle,
  }) async {
    if (_currentUploadState != UploadState.noPublish &&
        _currentUploadState != UploadState.publishSuccess &&
        _currentUploadState != UploadState.publishFailure) {
      ToastUtil.showMessage('您还有未发布完成的内容，请稍等');
      return false;
    }

    bool veritySuccess = await _verityPublish(context);
    if (veritySuccess) {
      publishModel.requestPublish(
        context,
        isUpdateBusiness,
        pickAllowType,
        uploadStateProgressBlock: (uploadState, totalProgressValue) {
          _currentUploadState = uploadState;
          eventBus.fire(PublishEvent(
            isUpdateAction: isUpdateBusiness,
            uploadState: uploadState,
            totalProgressValue: totalProgressValue,
          ));
          if (uploadStateProgressBlock != null) {
            uploadStateProgressBlock(uploadState, totalProgressValue);
          }
        },
        publishCompleteHandle: (ResponseModel responseModel) {
          if (responseModel.isSuccess) {
            _currentUploadState = UploadState.publishSuccess;
            String successWishId = publishModel.tsdemoId;
            if (isUpdateBusiness != true) {
              successWishId = responseModel.result['tsdemoId'];
            }
            if (publishModel.imageChooseModels.first.mediaType ==
                UploadMediaType.video) {
              // 是视频
              _savePathMap(
                  successWishId,
                  publishModel
                      .imageChooseModels.first.compressVideoBean.originPath,
                  publishModel
                      .coverImageChooseModel.frameDuration); // 保存视频本地路径映射
            }
            eventBus.fire(PublishEvent(
              isUpdateAction: isUpdateBusiness,
              uploadState: _currentUploadState,
              totalProgressValue: 100,
              successWishId: successWishId,
            ));
          } else {
            _currentUploadState = UploadState.publishFailure;
          }

          if (publishCompleteHandle != null) {
            publishCompleteHandle(responseModel);
          }
        },
      );
    }
    return veritySuccess;
  }

  ///验证发布内容权限
  Future<bool> _verityPublish(BuildContext context) async {
    // LoadingUtil.show(); // 发布内容防抖
    // await UserApi.getUserDetailInfo();
    // LoadingUtil.dismiss();

    bool canPublish = publishModel.canPublish(context);
    if (canPublish != true) {
      return false;
    }

    ///新增头像验证
    if (!WishVerifyWidget.hasPassVerify()) {
      WishVerifyWidget.showVerifyGuide(context);
      publishModel.pushCacheData(context); // 保存下
      return false;
    } else {
      return true;
    }
  }

  Future<File> downloadVideo(BuildContext context, String url) async {
    Directory tempDir = await getApplicationDocumentsDirectory();
    var videoThumbDir = Directory(tempDir.path + "/" + "video");
    if (!videoThumbDir.existsSync()) {
      debugPrint('getVideo 文件夹不存在，准备创建：${tempDir.path + "/" + "video"}');
      videoThumbDir.createSync();
    }

    String tempPath = videoThumbDir.path;
    // 图片保存路径
    var pathTag = url.substring(url.lastIndexOf('/') + 1, url.length);
    var savePath = tempPath + "/" + pathTag;
    debugPrint('下载视频保存路径:${tempPath + "/" + pathTag}');
    if (File(savePath).existsSync()) {
      debugPrint('视频已存在，直接返回');
      return File(savePath);
    }
    CancelToken cancelToken = CancelToken();

    StateSetter stateSetter;
    var progress = 0.0;
    showDialog(
        context: context,
        builder: (c) {
          return StatefulBuilder(builder: (context, setState) {
            stateSetter = setState;
            return Center(
              child: Container(
                padding:
                    const EdgeInsets.symmetric(vertical: 10, horizontal: 32),
                decoration: BoxDecoration(
                  borderRadius: BorderRadius.circular(10),
                  color: Colors.white,
                ),
                child: Column(
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    CircularProgressIndicator(
                      value: progress,
                      backgroundColor: const Color(0xfff1f1f1),
                      color: const Color(0xff333333),
                    ),
                    const SizedBox(
                      height: 6,
                    ),
                    Text("${(progress * 100).toInt()}%"),
                    const SizedBox(
                      height: 6,
                    ),
                    const Text('视频下载中'),
                    const SizedBox(
                      height: 12,
                    ),
                    GestureDetector(
                      onTap: () {
                        cancelToken.cancel();
                        Navigator.of(context).pop();
                      },
                      child: Container(
                        padding: const EdgeInsets.symmetric(
                            horizontal: 20, vertical: 2),
                        decoration: BoxDecoration(
                          borderRadius: BorderRadius.circular(60),
                          border: Border.all(color: const Color(0xFFFF7F00)),
                        ),
                        child: const Text(
                          '取消',
                          style: TextStyle(color: Color(0xFFFF7F00)),
                        ),
                      ),
                    ),
                  ],
                ),
              ),
            );
          });
        });
    var complete = false;
    await Dio().download(
      url,
      savePath,
      cancelToken: cancelToken,
      onReceiveProgress: (int count, int total) {
        progress = count / total;
        stateSetter.call(() {});
        if (count == total) {
          complete = true;
          Navigator.pop(context);
        }
      },
    );
    if (!complete) return null;
    _savePathMap(publishModel.tsdemoId, savePath, -1); // 保存视频本地路径映射
    return File(savePath);
  }

  void _savePathMap(
      String successWishId, String originPath, double frameDuration) async {
    var jsonString =
        await StorgeShared.getString(SP_PUBLISH_VIDEO_LOCAL_PATH_MAP);
    var jsonMap = jsonString == null ? {} : json.decode(jsonString);
    if (json is Map) {
      jsonMap[successWishId] = {
        "originPath": originPath,
        "frameDuration": frameDuration
      };
    } else {
      jsonMap = {
        successWishId: {
          "originPath": originPath,
          "frameDuration": frameDuration
        }
      };
    }
    jsonString = jsonEncode(jsonMap);
    await StorgeShared.setString(SP_PUBLISH_VIDEO_LOCAL_PATH_MAP, jsonString);
    debugPrint('保存视频本地路径映射成功:$jsonString');
  }
}
